package ch.epfl.lara.matcheck.ast.parser;

import scala.util.parsing.combinator.Parsers

trait ParsingHelper { self: Parsers =>
  
  /**
   * <p>
   *   Make a binary relation. Combines the elements of the list with the given operator from
   *   left to right.
   * </p>  
   *
   * @param head    : The first element
   * @param op_right: List of ~(operator,element)
   * @return        : A combined binary relation  
   */
  protected def mkBinaryRelation[T](head: T, op_right: List[~[(T,T)=>T,T]]): T = {
    op_right.foldLeft(head)((lhs,x) => {val ~(f,rhs) = x; f(lhs,rhs)})
  }
  
   

   /**
    * <p>
    *   Make a binary relation. The operator correspond to the binary relation that
    *	has to be applied to the left/right-hand-side.
    * </p>  
    *
    * @param flip : If true the lhs and rhs are inverted (flipped). 
    * @param op   : The binary operator
    * @param lhs  : The left-hand-side value
    * @param rhs  : The right-hand-side value
    * @return     : The result of applying lhs and rhs to the given operator  
    */ 
  private def createBinaryExpr[S,T](flip: Boolean)(op: (S,S) => T)(lhs: S,rhs:S): T = flip match {
     case false => op(lhs,rhs)
     case true => op(rhs,lhs)
  }      
   
    
  /**
   * <p>
   *	Make a comparison expression. The operator <code>op</code>correspond to 
   *	the comparison relation that has to be applied to <code>lhs</code> and 
   *	<code>rhs</code>. 
   *	The <code>flip</code> boolean is used to switch side to <code>lhs</code>
   *	and <code>rhs</code>. 
   * </p>
   *
   * @param flip : Flip <code>lhs</code> and <code>rhs</code>. 
   * @param op   : The binary operator
   * @param lhs  : The left-hand-side value
   * @param rhs  : The right-hand-side value
   * @return     : The result of applying lhs and rhs to the given operator  
   */
  protected def createCmpExpr[S,T](flip: Boolean)(op: (S,S) => T)(lhs: S,rhs:S): T = 
    createBinaryExpr(flip)(op)(lhs,rhs)
       
   
   
}
